import { Provide, Inject } from '@midwayjs/core';
import { Repository } from 'typeorm';
import { ActionLogOta } from '../../entity/firmware/actionLogOta.entity';
import { DictDataEntity } from '@entity/system/dictData.entity';
import { DictDataService } from '@service/system/dictData.service';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Gateway } from '@entity/firmware/gateway.entity';
import { Wristband } from '@entity/firmware/wristband.entity';
import { v4 as uuidv4 } from 'uuid';
import { OtaTaskService } from './ota_task.service';
import { FirmwareService } from './firmware.service';
import { OtaTask } from '@entity/firmware/ota_task.entity';
@Provide()
export class ActionLogOtaService {
  @Inject()
  dictDataService: DictDataService;
  @Inject()
  otaTaskService: OtaTaskService;
  @Inject()
  firmwareService: FirmwareService;
  @InjectEntityModel(ActionLogOta)
  actionLogRepo: Repository<ActionLogOta>;
  @InjectEntityModel(DictDataEntity)
  dictDataRepo: Repository<DictDataEntity>;
  @InjectEntityModel(Gateway)
  gatewayRepo: Repository<Gateway>;
  @InjectEntityModel(Wristband)
  wristbandRepo: Repository<Wristband>;
  @InjectEntityModel(OtaTask)
  otaTaskRepo: Repository<OtaTask>


  // **添加 OTA 操作日志**
  async createActionLog(data: Partial<ActionLogOta>) {
    let { taskid, gw_mac, wb_mac, action, value, time } = data;

    // 检查 taskid 是否存在
    const task = await this.otaTaskRepo.findOne({ where: { id: taskid } });
    if (!task) {
      console.error(`任务ID ${taskid} 不存在，无法创建 action log`);
      return; // 如果任务不存在，直接返回，不做任何操作
    }
    // 如果 gw_mac 或 wb_mac 是逗号分隔的字符串，拆分为数组
    let gwMacList = gw_mac.includes(',') ? gw_mac.split(',') : [gw_mac];
    let wbMacList = wb_mac.includes(',') ? wb_mac.split(',') : [wb_mac];
    console.log('debug3')
    // **3. 插入或更新 gw_mac 对应的 gateway 表**
    for (const gwMac of gwMacList) {
      let gatewayExists = await this.gatewayRepo.findOne({
        where: { mac: gwMac },
      });
      if (!gatewayExists) {
        try {
          await this.gatewayRepo.save({ mac: gwMac });
        } catch (err) {
          console.log('gateway err', err);
        }
      }
    }
    console.log('debug4')
    // **4. 插入或更新 wb_mac 对应的 wristband 表**
    for (const wbMac of wbMacList) {
      let wristbandExists = await this.wristbandRepo.findOne({
        where: { mac: wbMac },
      });
      if (!wristbandExists) {
        try {
          await this.wristbandRepo.save({ mac: wbMac, id: uuidv4() });
        } catch (err) {
          console.log('wristband err', err);
        }
      }
    }
    console.log('debug5')
    // **5. 创建 OTA 记录**
    const log = new ActionLogOta();
    log.taskid = taskid || null; // 使用传入的 taskid
    log.gw_mac = gw_mac || null;
    log.wb_mac = wb_mac || null;
    log.action = action;
    log.value = value.toString();
    log.time = time;
    console.log('debug6')
    // **6. 保存到数据库 action_log**
    try {
      console.log('debug7')
      await this.actionLogRepo.insert(log);
    } catch (err) {
      console.log('debug8')
      console.log('action_log err', err);
    }
  }

  // **获取所有 OTA 操作日志 (手环/网关）**
  async getAllActionLogs(param) {
    const { wb_mac, gw_mac, action, type, pageNum, pageSize } = param;

    if (!type) {
      throw new Error('请选择类型！');
    }

    // 初始化查询条件
    let queryBuilder = this.actionLogRepo.createQueryBuilder('log');

    // 根据 type 获取所有符合条件的日志
    queryBuilder
      .select(['log.id', 'log.taskid', 'log.gw_mac', 'log.wb_mac', 'log.action', 'log.type', 'log.time'])
      .where('log.type LIKE :type', { type: `%${type}%` })
      .orderBy('log.time', 'DESC'); // 按时间降序排序，获取最新的记录


    // 根据 type 设置过滤条件
    if (gw_mac) {
      queryBuilder.andWhere('log.gw_mac LIKE :gw_mac', { gw_mac: `%${gw_mac}%` });
    }
    if (wb_mac) {
      queryBuilder.andWhere('log.wb_mac LIKE :wb_mac', { wb_mac: `%${wb_mac}%` });
    }

    // 动态添加 action 和 type 的过滤条件
    if (action) queryBuilder.andWhere('log.action = :action', { action });

    // 1. 先克隆一个查询构造器用于计算总数（保持相同条件）
    const countQueryBuilder = queryBuilder.clone();

    // 2. 获取分组后的记录总数（按 taskid/gw_mac/wb_mac 分组）
    const total = await countQueryBuilder
      .select('COUNT(DISTINCT CONCAT(log.taskid, "-", log.gw_mac, "-", log.wb_mac))', 'count')
      .getRawOne()
      .then(res => parseInt(res.count, 10) || 0);

    // 获取每个 taskid 的最新记录（最大 id）
    const latestLogs = await queryBuilder
      .groupBy('log.taskid') // 按 taskid 分组
      .addGroupBy('log.gw_mac') // 按网关（gw_mac）分组
      .addGroupBy('log.wb_mac') // 按手环（wb_mac）分组
      .addSelect('MAX(log.id)', 'max_id') // 获取每个 taskid 对应的最大 id
      .skip((pageNum - 1) * pageSize) // 分页偏移量
      .take(pageSize) // 每页数量
      .getRawMany();

    // 提取最大 id 列表
    const ids = latestLogs.map((item) => item.max_id);

    // 根据最大 id 列表查询完整记录
    const logs = await this.actionLogRepo
      .createQueryBuilder('log')
      .whereInIds(ids)
      .orderBy('log.id', 'DESC')  // 按 id 降序排列
      .getMany();
    return {
      data: logs,
      total
    };
  }



  // **根据 ID 获取 OTA 操作日志**
  async getActionLogById(id: number) {
    // 通过 id 查询 actionLogRepo 表 的记录
    const log = await this.actionLogRepo.findOne({ where: { id } });
    // 通过 log 返回的 taskid 查询 ota_task 表 的记录
    if (log && log.taskid) {
      const task = await this.otaTaskService.getOta_TaskById(log.taskid);
      log.task = task;
    }
    // 通过 log.task 返回的 firmwareid 查询 firmware 表 的记录
    if (log && log.task && log.task.firmwareid) {
      const firmware = await this.firmwareService.getFirmwareById(log.task.firmwareid);
      log.task.firmware = firmware;
    }
    return log;
  }

  // **根据网关和手环 MAC 获取 OTA 操作日志**
  async getActionLogsByGwAndWb(param) {
    const { taskid, wb_mac, gw_mac, type, pageNum, pageSize } = param;

    // 创建主查询
    const query = this.actionLogRepo.createQueryBuilder('log');

    // 动态添加过滤条件
    if (taskid) query.andWhere('log.taskid = :taskid', { taskid });
    if (wb_mac) query.andWhere('log.wb_mac LIKE :wb_mac', { wb_mac: `%${wb_mac}%` });
    if (gw_mac) query.andWhere('log.gw_mac LIKE :gw_mac', { gw_mac: `%${gw_mac}%` });
    if (type) query.andWhere('log.type LIKE :type', { type: `%${type}%` });

    // 先按时间降序排列（对分组前的数据排序）
    query.orderBy('log.time', 'DESC');

    // 使用 GROUP BY 去重
    query.groupBy('log.taskid, log.wb_mac, log.gw_mac, log.type, log.time');

    // 创建单独的计数查询（不使用分组）
    const countQuery = this.actionLogRepo.createQueryBuilder('log')
      .select('COUNT(DISTINCT CONCAT(log.taskid, log.wb_mac, log.gw_mac, log.type, log.time))', 'count');

    // 应用相同的过滤条件
    if (taskid) countQuery.andWhere('log.taskid = :taskid', { taskid });
    if (wb_mac) countQuery.andWhere('log.wb_mac LIKE :wb_mac', { wb_mac: `%${wb_mac}%` });
    if (gw_mac) countQuery.andWhere('log.gw_mac LIKE :gw_mac', { gw_mac: `%${gw_mac}%` });
    if (type) countQuery.andWhere('log.type LIKE :type', { type: `%${type}%` });

    const totalResult = await countQuery.getRawOne();
    const total = parseInt(totalResult?.count || 0, 10);

    // 分页处理
    if (pageNum && pageSize) {
      query.offset((pageNum - 1) * pageSize).limit(pageSize);
    }

    // 获取数据
    const data = await query.getMany();

    return {
      total,
      data
    };
  }


  // **更新 OTA 操作日志**
  async updateActionLog(id: number, updateData: Partial<ActionLogOta>) {
    const log = await this.getActionLogById(id);
    if (!log) return null;

    Object.assign(log, updateData);
    return await this.actionLogRepo.save(log);
  }

  // **删除 OTA 操作日志**
  async deleteActionLog(id: string) {
    const result = await this.actionLogRepo.delete(id);
    return result.affected > 0;
  }
}
